home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / util / edit / jed207.lha / src / jed.lha / render.c < prev    next >
C/C++ Source or Header  |  1992-09-18  |  14KB  |  554 lines

  1.  
  2. /*
  3.  * RENDER.C
  4.  * (c) 1992 J.Harper
  5.  */
  6.  
  7. #include "jed.h"
  8. #include "jed_protos.h"
  9.  
  10. #define TEXTPEN  1
  11. #define BLOCKPEN 2
  12. #define CURSPEN  3
  13.  
  14. Prototype   VOID        pentocursor     (VOID);
  15. Prototype   VOID        pentoline       (WORD);
  16. Prototype   VOID        pentopos        (WORD, WORD);
  17. Prototype   VOID        setpospen       (WORD, LONG);
  18. Prototype   VOID        cursor          (BOOL);
  19. Local       VOID        drawbit         (STRPTR, WORD, WORD);
  20. Prototype   VOID        drawline        (LINE *, LONG);
  21. Prototype   VOID        drawlinepart    (LINE *, LONG, WORD);
  22. Prototype   VOID        redrawall       (VOID);
  23. Prototype   VOID        redrawallfrom   (WORD, LONG);
  24. Prototype   VOID        redrawline      (LONG);
  25. Prototype   VOID        redrawlinefrom  (WORD, LONG);
  26. Prototype   VOID        redrawcmdline   (STRPTR, STRPTR, LONG, LONG);
  27. Prototype   VOID        redrawcmdlinefrom(STRPTR, STRPTR, LONG, LONG, WORD);
  28. Prototype   VOID        restorecmdline  (VOID);
  29. Prototype   VOID        cmdlncursor     (BOOL);
  30. Prototype   VOID        refresh         (VOID);
  31. Prototype   VOID        setrefresh      (WORD, WORD, LONG);
  32. Prototype   VOID        refreshallviews (TX *);
  33.  
  34. VOID
  35. pentocursor(VOID)
  36. {
  37.     VW *vw = CurrVW;
  38.     Move(vw->vw_Rp, vw->vw_XStartPix + ((vw->vw_CursorPos.pos_Col - vw->vw_StartCol) * vw->vw_FontX), vw->vw_FontStart + ((vw->vw_CursorPos.pos_Line - vw->vw_StartLine) * vw->vw_FontY));
  39. }
  40.  
  41. /*
  42.  * note actual y coordinate not line number
  43.  */
  44. VOID
  45. pentoline(WORD yPos)
  46. {
  47.     VW *vw = CurrVW;
  48.     Move(vw->vw_Rp, vw->vw_XStartPix, vw->vw_FontStart + (yPos * vw->vw_FontY));
  49. }
  50.  
  51. /*
  52.  * this also takes coordinates...
  53.  */
  54. VOID
  55. pentopos(WORD xPos, WORD yPos)
  56. {
  57.     VW *vw = CurrVW;
  58.     Move(vw->vw_Rp, vw->vw_XStartPix + (xPos * vw->vw_FontX), vw->vw_FontStart + (yPos * vw->vw_FontY));
  59. }
  60.  
  61. /*
  62.  * ...but this wants column and line numbers (confusing, eh?)
  63.  */
  64. VOID
  65. setpospen(WORD col, LONG line)
  66. {
  67.     if(posinblock(col, line))
  68.     SetAPen(CurrVW->vw_Rp, BLOCKPEN);
  69.     else
  70.     SetAPen(CurrVW->vw_Rp, TEXTPEN);
  71.     SetDrMd(CurrVW->vw_Rp, JAM2);
  72. }
  73.  
  74. VOID
  75. cursor(BOOL status)
  76. {
  77.     VW *vw = CurrVW;
  78.     if((!vw->vw_Sleeping) && (!vw->vw_DisplayLock))
  79.     {
  80.     LINE *line = vw->vw_Tx->tx_Lines + vw->vw_CursorPos.pos_Line;
  81.     WORD cursoff = vw->vw_CursorPos.pos_Col;
  82.     struct RastPort *rp = vw->vw_Rp;
  83.  
  84.     if(status)
  85.     {
  86.         SetAPen(rp, CURSPEN);
  87.         SetDrMd(rp, JAM1 | INVERSVID);
  88.     }
  89.     else if(cursinblock())
  90.     {
  91.         SetAPen(rp, BLOCKPEN);
  92.         SetDrMd(rp, JAM2);
  93.     }
  94.     else
  95.     {
  96.         SetAPen(rp, TEXTPEN);
  97.         SetDrMd(rp, JAM2);
  98.     }
  99.     pentocursor();
  100.     if((cursoff + 1) >= line->ln_Strlen)
  101.         Text(rp, " ", 1);
  102.     else
  103.         Text(rp, line->ln_Line + cursoff, 1);
  104.     }
  105. }
  106.  
  107. /*
  108.  * draws a section of a line of text, beg and end are x ordinates
  109.  */
  110. Local VOID
  111. drawbit(STRPTR str, WORD beg, WORD end)
  112. {
  113.     VW *vw = CurrVW;
  114.     WORD startx = vw->vw_StartCol;
  115.     WORD endx = vw->vw_MaxX + startx + 1;
  116.  
  117.     if(end > startx)
  118.     {
  119.     WORD length;
  120.     if(beg < startx)
  121.         beg = startx;
  122.     if(end > endx)
  123.         end = endx;
  124.     if((length = end - beg - 1) > 0)
  125.         Text(vw->vw_Rp, str + beg, length);
  126.     }
  127. }
  128.  
  129. /*
  130.  * pen should be at start of line to draw (line should be cleared first)
  131.  */
  132. VOID
  133. drawline(LINE *line, LONG lineNum)
  134. {
  135.     VW *vw = CurrVW;
  136.     struct RastPort *rp = vw->vw_Rp;
  137.  
  138.     if(vw->vw_BlockStatus)
  139.     {
  140.     SetAPen(rp, TEXTPEN);
  141.     SetDrMd(rp, JAM2);
  142.     drawbit(line->ln_Line, 0, line->ln_Strlen);
  143.     }
  144.     else
  145.     {
  146.     WORD flag = lineinblock(lineNum);
  147.  
  148.     switch(flag)
  149.     {
  150.         case 0:     /* none of line in block */
  151.         SetAPen(rp, TEXTPEN);
  152.         SetDrMd(rp, JAM2);
  153.         drawbit(line->ln_Line, 0, line->ln_Strlen);
  154.         break;
  155.         case 1:     /* whole of line in block */
  156.         SetAPen(rp, BLOCKPEN);
  157.         SetDrMd(rp, JAM2);
  158.         drawbit(line->ln_Line, 0, line->ln_Strlen);
  159.         break;
  160.         case 2:     /* start of line in block */
  161.         SetAPen(rp, BLOCKPEN);
  162.         SetDrMd(rp, JAM2);
  163.         drawbit(line->ln_Line, 0, vw->vw_Block[1].pos_Col + 1);
  164.         SetAPen(rp, TEXTPEN);
  165.         drawbit(line->ln_Line, vw->vw_Block[1].pos_Col, line->ln_Strlen);
  166.         break;
  167.         case 3:     /* end of line in block */
  168.         SetAPen(rp, TEXTPEN);
  169.         SetDrMd(rp, JAM2);
  170.         drawbit(line->ln_Line, 0, vw->vw_Block[0].pos_Col + 1);
  171.         SetAPen(rp, BLOCKPEN);
  172.         drawbit(line->ln_Line, vw->vw_Block[0].pos_Col, line->ln_Strlen);
  173.         break;
  174.         case 4:     /* middle of line in block */
  175.         SetAPen(rp, TEXTPEN);
  176.         SetDrMd(rp, JAM2);
  177.         drawbit(line->ln_Line, 0, vw->vw_Block[0].pos_Col + 1);
  178.         SetAPen(rp, BLOCKPEN);
  179.         drawbit(line->ln_Line, vw->vw_Block[0].pos_Col, vw->vw_Block[1].pos_Col + 1);
  180.         SetAPen(rp, TEXTPEN);
  181.         drawbit(line->ln_Line, vw->vw_Block[1].pos_Col, line->ln_Strlen);
  182.         break;
  183.     }
  184.     }
  185. }
  186.  
  187. /*
  188.  * pen should be at first draw position
  189.  */
  190. VOID
  191. drawlinepart(LINE *line, LONG lineNum, WORD xStart)
  192. {
  193.     VW *vw = CurrVW;
  194.     struct RastPort *rp = vw->vw_Rp;
  195.  
  196.     if(vw->vw_BlockStatus)
  197.     {
  198.     SetAPen(rp, TEXTPEN);
  199.     SetDrMd(rp, JAM2);
  200.     drawbit(line->ln_Line, xStart, line->ln_Strlen);
  201.     }
  202.     else
  203.     {
  204.     WORD flag = lineinblock(lineNum);
  205.  
  206.     switch(flag)
  207.     {
  208.         case 0:     /* none of line in block */
  209.         SetAPen(rp, TEXTPEN);
  210.         SetDrMd(rp, JAM2);
  211.         drawbit(line->ln_Line, xStart, line->ln_Strlen);
  212.         break;
  213.         case 1:     /* whole of line in block */
  214.         SetAPen(rp, BLOCKPEN);
  215.         SetDrMd(rp, JAM2);
  216.         drawbit(line->ln_Line, xStart, line->ln_Strlen);
  217.         break;
  218.         case 2:     /* start of line in block */
  219.         WORD block1col = vw->vw_Block[1].pos_Col;
  220.         SetAPen(rp, BLOCKPEN);
  221.         SetDrMd(rp, JAM2);
  222.         if(xStart < block1col)
  223.             drawbit(line->ln_Line, xStart, block1col + 1);
  224.         else
  225.             block1col = xStart;
  226.         SetAPen(rp, TEXTPEN);
  227.         drawbit(line->ln_Line, block1col, line->ln_Strlen);
  228.         break;
  229.         case 3:     /* end of line in block */
  230.         WORD block0col = vw->vw_Block[0].pos_Col;
  231.         SetAPen(rp, TEXTPEN);
  232.         SetDrMd(rp, JAM2);
  233.         if(xStart < block0col)
  234.             drawbit(line->ln_Line, xStart, block0col + 1);
  235.         else
  236.             block0col = xStart;
  237.         SetAPen(rp, BLOCKPEN);
  238.         drawbit(line->ln_Line, block0col, line->ln_Strlen);
  239.         break;
  240.         case 4:     /* middle of line in block */
  241.         WORD block0col = vw->vw_Block[0].pos_Col;
  242.         WORD block1col = vw->vw_Block[1].pos_Col;
  243.         SetAPen(rp, TEXTPEN);
  244.         SetDrMd(rp, JAM2);
  245.         if(xStart < block0col)
  246.             drawbit(line->ln_Line, xStart, block0col + 1);
  247.         else
  248.             block0col = xStart;
  249.         SetAPen(rp, BLOCKPEN);
  250.         if(block0col < block1col)
  251.             drawbit(line->ln_Line, block0col, block1col + 1);
  252.         else
  253.             block1col = block0col;
  254.         SetAPen(rp, TEXTPEN);
  255.         drawbit(line->ln_Line, block1col, line->ln_Strlen);
  256.         break;
  257.     }
  258.     }
  259. }
  260.  
  261. VOID
  262. redrawall(VOID)
  263. {
  264.     VW *vw = CurrVW;
  265.     LONG linenum = vw->vw_StartLine;
  266.     LINE *line = vw->vw_Tx->tx_Lines + linenum;
  267.     WORD y = 0;
  268.  
  269.     SetAPen(vw->vw_Rp, 0);
  270.     SetDrMd(vw->vw_Rp, JAM2);
  271.     RectFill(vw->vw_Rp, vw->vw_XStartPix, vw->vw_YStartPix, vw->vw_XEndPix - 1, vw->vw_YEndPix - 1);
  272.  
  273.     while((y < vw->vw_MaxY) && (linenum < vw->vw_Tx->tx_NumLines))
  274.     {
  275.     pentoline(y);
  276.     drawline(line, linenum);
  277.     y++;
  278.     linenum++;
  279.     line++;
  280.     }
  281. }
  282.  
  283. VOID
  284. redrawallfrom(WORD col, LONG lineNum)
  285. {
  286.     VW *vw = CurrVW;
  287.     LINE *line = vw->vw_Tx->tx_Lines + lineNum;
  288.     WORD y = lineNum - vw->vw_StartLine;
  289.     UWORD yord = (y * vw->vw_FontY) + vw->vw_YStartPix;
  290.  
  291.     if(col < vw->vw_StartCol)
  292.     col = vw->vw_StartCol;
  293.     if((y >= 0) && (y < vw->vw_MaxY))
  294.     {
  295.     SetAPen(vw->vw_Rp, 0);
  296.     SetDrMd(vw->vw_Rp, JAM2);
  297.     RectFill(vw->vw_Rp, ((col - vw->vw_StartCol) * vw->vw_FontX) + vw->vw_XStartPix, yord, vw->vw_XEndPix - 1, yord + vw->vw_FontY - 1);
  298.     pentopos(col - vw->vw_StartCol, y);
  299.     drawlinepart(line, lineNum, col);
  300.     line++;
  301.     lineNum++;
  302.     y++;
  303.     yord += vw->vw_FontY;
  304.     }
  305.     else
  306.     {
  307.     y = 0;
  308.     yord = vw->vw_YStartPix;
  309.     lineNum = vw->vw_StartLine;
  310.     line = vw->vw_Tx->tx_Lines + lineNum;
  311.     }
  312.     if(y < vw->vw_MaxY)
  313.     {
  314.     SetAPen(vw->vw_Rp, 0);
  315.     SetDrMd(vw->vw_Rp, JAM2);
  316.     RectFill(vw->vw_Rp, vw->vw_XStartPix, yord, vw->vw_XEndPix - 1, vw->vw_YEndPix - 1);
  317.  
  318.     while((y < vw->vw_MaxY) && (lineNum < vw->vw_Tx->tx_NumLines))
  319.     {
  320.         pentoline(y);
  321.         drawline(line, lineNum);
  322.         y++;
  323.         lineNum++;
  324.         line++;
  325.     }
  326.     }
  327. }
  328.  
  329. VOID
  330. redrawline(LONG lineNum)
  331. {
  332.     VW *vw = CurrVW;
  333.     UWORD yord = ((lineNum - vw->vw_StartLine) * vw->vw_FontY) + vw->vw_YStartPix;
  334.  
  335.     SetAPen(vw->vw_Rp, 0);
  336.     SetDrMd(vw->vw_Rp, JAM2);
  337.     RectFill(vw->vw_Rp, vw->vw_XStartPix, yord, vw->vw_XEndPix - 1, yord + vw->vw_FontY - 1);
  338.  
  339.     pentoline(lineNum - vw->vw_StartLine);
  340.     drawline(vw->vw_Tx->tx_Lines + lineNum, lineNum);
  341. }
  342.  
  343. VOID
  344. redrawlinefrom(WORD col, LONG lineNum)
  345. {
  346.     VW *vw = CurrVW;
  347.     if(col < vw->vw_StartCol)
  348.     col = vw->vw_StartCol;
  349.     if((lineNum >= vw->vw_StartLine) && (lineNum < vw->vw_StartLine + vw->vw_MaxY))
  350.     {
  351.     UWORD yord = ((lineNum - vw->vw_StartLine) * vw->vw_FontY) + vw->vw_YStartPix;
  352.  
  353.     SetAPen(vw->vw_Rp, 0);
  354.     SetDrMd(vw->vw_Rp, JAM2);
  355.     RectFill(vw->vw_Rp, vw->vw_XStartPix + ((col - vw->vw_StartCol) * vw->vw_FontX), yord, vw->vw_XEndPix - 1, yord + vw->vw_FontY - 1);
  356.  
  357.     pentopos(col - vw->vw_StartCol, lineNum - vw->vw_StartLine);
  358.     drawlinepart(vw->vw_Tx->tx_Lines + lineNum, lineNum, col);
  359.     }
  360. }
  361.  
  362. /*
  363.  */
  364. VOID
  365. redrawcmdline(STRPTR prompt, STRPTR cmdLine, LONG promptLen, LONG cmdLen)
  366. {
  367.     VW *vw = CurrVW;
  368.     struct RastPort *rp = vw->vw_Rp;
  369.     WORD yclr = ((vw->vw_MaxY - 1) * vw->vw_FontY) + vw->vw_YStartPix;
  370.  
  371.     SetAPen(rp, 0);
  372.     SetDrMd(rp, JAM2);
  373.     RectFill(rp, vw->vw_XStartPix, yclr, vw->vw_XEndPix - 1, yclr + vw->vw_FontY - 1);
  374.  
  375.     SetAPen(rp, TEXTPEN);
  376.     Move(rp, vw->vw_XStartPix, ((vw->vw_MaxY - 1) * vw->vw_FontY) + vw->vw_FontStart);
  377.     drawbit(prompt, 0, promptLen + 1);
  378.     drawbit(cmdLine - promptLen, promptLen, cmdLen + promptLen + 1);
  379. }
  380.  
  381. VOID
  382. redrawcmdlinefrom(STRPTR prompt, STRPTR cmdLine, LONG promptLen, LONG cmdLen, WORD startPos)
  383. {
  384.     VW *vw = CurrVW;
  385.     struct RastPort *rp = vw->vw_Rp;
  386.     WORD yclr = ((vw->vw_MaxY - 1) * vw->vw_FontY) + vw->vw_YStartPix;
  387.     WORD xord;
  388.  
  389.     if(startPos < vw->vw_StartCol)
  390.     startPos = vw->vw_StartCol;
  391.     if(startPos < (vw->vw_StartCol + vw->vw_MaxX))
  392.     {
  393.     xord = vw->vw_XStartPix + (startPos * vw->vw_FontX);
  394.     SetAPen(rp, 0);
  395.     SetDrMd(rp, JAM2);
  396.     RectFill(rp, xord, yclr, vw->vw_XEndPix - 1, yclr + vw->vw_FontY - 1);
  397.     SetAPen(rp, TEXTPEN);
  398.     Move(rp, xord, ((vw->vw_MaxY - 1) * vw->vw_FontY) + vw->vw_FontStart);
  399.     if(startPos < promptLen)
  400.     {
  401.         drawbit(prompt, startPos, promptLen + 1);
  402.         drawbit(cmdLine - promptLen, promptLen, cmdLen + promptLen + 1);
  403.     }
  404.     else
  405.         drawbit(cmdLine - promptLen, startPos, cmdLen + promptLen + 1);
  406.     }
  407. }
  408.  
  409. /*
  410.  * redraws the line which the command line overwrote
  411.  */
  412. VOID
  413. restorecmdline(VOID)
  414. {
  415.     VW *vw = CurrVW;
  416.     UWORD yord = ((vw->vw_MaxY - 1) * vw->vw_FontY) + vw->vw_YStartPix;
  417.     LONG linenum = vw->vw_StartLine + vw->vw_MaxY - 1;
  418.  
  419.     SetAPen(vw->vw_Rp, 0);
  420.     SetDrMd(vw->vw_Rp, JAM2);
  421.     RectFill(vw->vw_Rp, vw->vw_XStartPix, yord, vw->vw_XEndPix - 1, yord + vw->vw_FontY - 1);
  422.     if(vw->vw_Tx->tx_NumLines > linenum)
  423.     {
  424.     pentoline(vw->vw_MaxY - 1);
  425.     drawline(vw->vw_Tx->tx_Lines + linenum, linenum);
  426.     }
  427. }
  428.  
  429. /*
  430.  * draws the cursor for the command line
  431.  */
  432. VOID
  433. cmdlncursor(BOOL status)
  434. {
  435.     VW *vw = CurrVW;
  436.     struct RastPort *rp = vw->vw_Rp;
  437.     if(status)
  438.     {
  439.     SetAPen(rp, CURSPEN);
  440.     SetDrMd(rp, JAM2 | INVERSVID);
  441.     }
  442.     else
  443.     {
  444.     SetAPen(rp, TEXTPEN);
  445.     SetDrMd(rp, JAM2);
  446.     }
  447.     Move(rp, vw->vw_XStartPix + ((vw->vw_CursorPos.pos_Col - vw->vw_StartCol) * vw->vw_FontX), ((vw->vw_MaxY - 1) * vw->vw_FontY) + vw->vw_FontStart);
  448.     Text(rp, " ", 1);
  449. }
  450.  
  451. /*
  452.  * The idea with this routine is that each function used to perform some type
  453.  * of operation OR's the refresh type that it needs into the vw_RefreshType
  454.  * flag. Then at the end of the operation the highest level routine calls
  455.  * refresh() and the smallest type of refresh possible is performed.
  456.  *
  457.  * the only problem is that most of the low level editing functions in
  458.  * edit.c don't set the refresh flag, oh well...
  459.  */
  460. VOID
  461. refresh(VOID)
  462. {
  463.     VW *vw = CurrVW;
  464.     if(vw && (!vw->vw_DeferRefresh))
  465.     {
  466.     if((!vw->vw_Sleeping) && (!vw->vw_DisplayLock))
  467.     {
  468.         WORD refflags = vw->vw_RefreshType;
  469.         if(refflags & RFF_ALL)
  470.         redrawall();
  471.         else if(refflags & RFF_ALLFROM)
  472.         {
  473.         if(vw->vw_RefreshPos.pos_Line < vw->vw_StartLine)
  474.         {
  475.             vw->vw_RefreshPos.pos_Line = vw->vw_StartLine;
  476.             vw->vw_RefreshPos.pos_Col = 0;
  477.         }
  478.         if(vw->vw_RefreshPos.pos_Line <= vw->vw_StartLine + vw->vw_MaxY)
  479.             redrawallfrom(vw->vw_RefreshPos.pos_Col, vw->vw_RefreshPos.pos_Line);
  480.         }
  481.         else if(refflags & RFF_CURSLINE)
  482.         redrawline(vw->vw_CursorPos.pos_Line);
  483.         else if(refflags & RFF_LINEFROM)
  484.         {
  485.         if((vw->vw_RefreshPos.pos_Line >= vw->vw_StartLine) && (vw->vw_RefreshPos.pos_Line <= vw->vw_StartLine + vw->vw_MaxY))
  486.             redrawlinefrom(vw->vw_RefreshPos.pos_Col, vw->vw_RefreshPos.pos_Line);
  487.         }
  488.         vw->vw_RefreshType = 0;
  489.         vw->vw_LastRefresh = vw->vw_Tx->tx_Changes;
  490.     }
  491.     }
  492.     else if(vw)
  493.     vw->vw_DeferRefresh--;
  494. }
  495.  
  496. /*
  497.  * This must be called if you want to set the refresh position, this routine
  498.  * makes it all work :-)
  499.  */
  500. VOID
  501. setrefresh(WORD refFlag, WORD refX, LONG refY)
  502. {
  503.     VW *vw = CurrVW;
  504.     if(refFlag & (RFF_LINEFROM | RFF_ALLFROM))
  505.     {
  506.     if(vw->vw_RefreshType & (RFF_ALLFROM | RFF_LINEFROM))
  507.     {
  508.         if(vw->vw_RefreshPos.pos_Line > refY)
  509.         {
  510.         vw->vw_RefreshType |= RFF_ALLFROM;
  511.         vw->vw_RefreshPos.pos_Col = refX;
  512.         vw->vw_RefreshPos.pos_Line = refY;
  513.         }
  514.         else if((vw->vw_RefreshPos.pos_Line == refY) && (vw->vw_RefreshPos.pos_Col > refX))
  515.         {
  516.         vw->vw_RefreshType |= refFlag;
  517.         vw->vw_RefreshPos.pos_Col = refX;
  518.         }
  519.         else
  520.         vw->vw_RefreshType |= RFF_ALLFROM;
  521.     }
  522.     else
  523.     {
  524.         vw->vw_RefreshType |= refFlag;
  525.         vw->vw_RefreshPos.pos_Col = refX;
  526.         vw->vw_RefreshPos.pos_Line = refY;
  527.     }
  528.     }
  529.     else
  530.     vw->vw_RefreshType |= refFlag;
  531. }
  532.  
  533. /*
  534.  * this function steps through all views attached to this file refresh()'ing
  535.  * each one.
  536.  */
  537. VOID
  538. refreshallviews(TX *tx)
  539. {
  540.     VW *oldvw = CurrVW;
  541.     for(CurrVW = (VW *)tx->tx_Views.mlh_Head; CurrVW->vw_Node.mln_Succ; CurrVW = (VW *)CurrVW->vw_Node.mln_Succ)
  542.     {
  543.     if(!CurrVW->vw_Sleeping)
  544.     {
  545.         cursor(OFF);
  546.         refresh();
  547.         cursor(ON);
  548.     }
  549.     }
  550.     CurrVW = oldvw;
  551.     cursor(OFF);
  552. }
  553.  
  554.